import ctypes
import json
import random
import socket
import threading
import time
import os

import pystray
from PIL import Image

tsclibrary = ctypes.WinDLL(".\\TSCLIB.dll")


# 工具方法开始
#  pip install pystray -i https://pypi.tuna.tsinghua.edu.cn/simple
#  pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple

def strToBytes(my_string):
    # 指定目标字节数组的长度
    desired_length = 10

    # 将字符串编码为字节数组（默认使用UTF-8编码）
    byte_array = my_string.encode()

    # 计算需要填充的字节数
    padding_length = desired_length - len(byte_array)

    # 填充字节数组（可以选择不同的填充字符，例如空格）
    if padding_length > 0:
        padding = b' ' * padding_length
        byte_array += padding

    # 打印固定长度的字节数组
    return byte_array


def bytesToStr(byte_array):
    # 将字节数组解码为字符串（使用ASCII编码）
    my_string = byte_array.decode()

    # 打印字符串
    print(my_string.strip())
    return my_string.strip()


def method2(content, numbers):
    string_list = content.split(';')
    name = string_list[0]
    number = string_list[1]
    spec = string_list[2]
    code = string_list[3]
    supplier = string_list[4]
    date = string_list[5]
    tsclibrary.sendcommandW("SIZE 60 mm, 40 mm")
    tsclibrary.sendcommandW("GAP 0.1 mm, 0.1 mm")
    tsclibrary.sendcommandW("DIRECTION 1")
    tsclibrary.sendcommandW("CLS")
    tsclibrary.sendcommandW('SPEED 4')
    tsclibrary.sendcommandW('SETBOLD 1');
    tsclibrary.sendcommandW('DENSITY 8')
    tsclibrary.windowsfontW("50", "140", "50", "0", "1.2", "1.2", 'msyhbd', '物料名称:' + name)
    tsclibrary.windowsfontW("50", "190", "50", "0", "1.2", "1.2", 'msyhbd', '批号:' + number)
    tsclibrary.windowsfontW("50", "240", "50", "0", "1.2", "1.2", 'msyhbd', '规格型号:' + spec)
    tsclibrary.windowsfontW("50", "290", "50", "0", "1.2", "1.2", 'msyhbd', '物料编码:' + code)
    tsclibrary.windowsfontW("50", "340", "50", "0", "1.2", "1.2", 'msyhbd', '供应商:' + supplier)
    tsclibrary.windowsfontW("500", "400", "50", "0", "1.2", "1.2", 'msyhbd', date)

    tsclibrary.printlabelW(f'{numbers}', "1")
    tsclibrary.closeport()


# 工具方法结束

def printer_loading(content, printer, numbers):
    print("开始打印")
    tsclibrary.openportW(printer)
    try:
        method2(content, numbers)
    except Exception as e:
        print("打印发生异常：" + e)
    print("打印完成")


def register(server_host, server_port):
    # 最大尝试次数
    max_retries = 10000

    # 循环尝试连接
    for retry in range(max_retries):
        try:
            client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            client_socket.connect((server_host, server_port))
            print(f'成功连接到服务器 {server_host}:{server_port}')
            break  # 如果连接成功，跳出循环
        except ConnectionRefusedError:
            print(f'连接失败，尝试重新连接 ({retry + 1}/{max_retries})')
            time.sleep(20)  # 等待5秒后重试
        except Exception as e:
            print(f'发生其他异常：{str(e)}')
            break  # 如果发生其他异常，停止程序

    else:
        print(f'无法连接到服务器 {server_host}:{server_port}，已达到最大尝试次数')
        # 这里可以添加处理连接失败的逻辑，例如记录日志或采取其他措施
        raise SystemExit

    # 要添加的字节(注册)
    # new_byte = b'\x01'

    # 注册识别号到服务端
    registerPackage = config_data['IdentificationCode'].to_bytes(4, 'big')

    client_socket.send(registerPackage)
    return client_socket


def client(config_data, stop_flag):
    # 服务器主机和端口
    server_host = config_data['remoteHost']  # 服务器的IP地址
    server_port = config_data['remotePort']  # 服务器的端口号，与服务器配置一致
    isPrint = config_data['isPrint']  # 是否进行打印
    printer = config_data['printer'].strip()

    # 创建一个TCP socket
    client_socket = register(server_host, server_port)
    print(f"已成功连接到服务端,等待接收数据")
    while True:
        try:
            data = client_socket.recv(1026)
            # if data.startswith(b'\x02\x01'):
            # 使用切片操作去除头部指定字节
            # printerName = data[len(b'\x02\x01'):258].decode().strip()
            # content = data[258:].decode().strip()
            # printerName=data[0:256].decode().strip(
            data = data.decode().strip()
            json_object = json.loads(data)
            name = json_object["name"]
            numbers = json_object["numbers"]
            content = json_object["content"]
            print('打印机名称：', name)
            print('打印内容：', content)
            # 进行打印
            if isPrint:
                time.sleep(5)
                thread2 = threading.Thread(target=printer_loading, args=(content, name, numbers))
                thread2.start()
                # printer_loading(content, name)
        except Exception as e:
            print(e)
            # 等待5秒进行重连
            print("等待5秒")
            time.sleep(5)
            client_socket = register(server_host, server_port)
            print(f"已重新成功连接到服务端,等待接收文件")


printerName = []


# 右下角图标
def show_tray_icon():
    image = Image.open("icon.ico")

    icon = pystray.Icon("name", image, "智能打印")

    icon.run()


if __name__ == "__main__":

    # 配置开机自动启动 todo

    # 读取配置文件
    with open('config.json', 'r', encoding='utf-8') as file:
        config_data = json.load(file)
    # 判断是否有识别码
    if 'IdentificationCode' not in config_data:
        random_number = random.randint(100000000, 999999999)
        print('初始化：', random_number)
        config_data['IdentificationCode'] = random_number
        with open('config.json', 'w') as file:
            json.dump(config_data, file)
    print(config_data)

    # 异步开启tcp客户端接受文件
    # 创建线程
    thread = threading.Thread(target=client, args=(config_data, "stop_flag"))
    # 启动线程
    thread.start()
    # 配置到左下角
    show_tray_icon()
